home *** CD-ROM | disk | FTP | other *** search
- /*
- CDPlay - An XFCN to play absolute minute, second, block
- ©Apple Computer, Inc. 1988
- All Rights Reserved.
-
- 88/10/08 BL°B First Version
-
- To compile and link this file using Macintosh Programmer's Workshop,
-
- C -q2 CDPlay.c
- link -sn Main=CDPlay -sn STDIO=CDPlay ∂
- -sn INTENV=CDPlay -rt XFCN=42 ∂
- -m CDPLAY CDPlay.c.o "{CLibraries}"CRuntime.o ∂
- "{CLibraries}"StdCLib.o ∂
- -o HyperCommands
-
- This link directive puts the XCMD in the file "HyperCommands".
- Substitute the name of the stack you want it in. To move XCMDs
- between stacks, use ResEdit. They can be in an individual stack,
- the Home stack, the HyperCard application, or the System File.
-
- */
-
- #include <cd.h>
-
- /* prototype definitions for functions */
- void ExtractBCD(char *, short *);
- OSErr APlay(XCmdBlockPtr, short, short, short, short);
- OSErr BCDPosition(short, short *, short *, short *);
- OSErr AStop(XCmdBlockPtr, short, short, short, short);
- OSErr FindTrack1BCD(short, short *, short *, short *);
-
- /* **** WARNING: DO NOT USE GLOBAL VARIABLES! **** */
-
-
- /************************************************************************
- *
- * Function: CDPlay
- *
- * Purpose: play absolute minute, second and block
- *
- * Returns: result of driver call to play
- * normally 0, but could have parameter error or
- * other error if non-existent block is specified
- *
- * Side Effects:
- *
- * Description: We need three parameters or no parameters:
- * 1) the minute
- * 2) the second
- * 3) the block
- * Extract the minute, second and block and start
- * playing at that point.
- * If we don't get any parameters, start play at the
- * current position.
- *
- * We may also get three additional parameters which
- * specify the stop address. If so, set up a stop
- * at that address.
- *
- ************************************************************************/
- pascal void
- CDPlay(paramPtr)
- XCmdBlockPtr paramPtr;
- {
- Str31 returnString;
- OSErr result;
- short minute;
- short second;
- short block;
- short ioRefNum;
- Handle refHandle;
-
- /* Get the global ioRefNum and convert it. */
- refHandle = GetGlobal(paramPtr, GLOBALNAME);
- ioRefNum = atoi(*(refHandle));
- DisposHandle(refHandle);
- ioRefNum &= 0xFFFF; /* remove vRefNum; not needed. */
-
- /* Must be three parameters, or none (or six) */
- switch (paramPtr->paramCount) {
- case 0:
- result = BCDPosition(ioRefNum, &minute, &second, &block);
-
- if (result == noErr)
- result = APlay(paramPtr, ioRefNum, minute, second, block);
-
- if (result == paramErr)
- { /* we're trying to play an invalid position.
- ** find the start of track 1, and try to play there. */
-
- result = FindTrack1BCD(ioRefNum, &minute, &second, &block);
-
- if (result == noErr)
- result = APlay(paramPtr, ioRefNum, minute, second, block);
- }
- break;
- case 3:
- /* First param is minute. Convert it to a BCD number */
- ExtractBCD((char *)*(paramPtr->params[0]), &minute);
-
- /* Second param is second. Convert it to a BCD number */
- ExtractBCD((char *)*(paramPtr->params[1]), &second);
-
- /* Third param is block. Convert it to a BCD number */
- ExtractBCD((char *)*(paramPtr->params[2]), &block);
-
- result = APlay(paramPtr, ioRefNum, minute, second, block);
- break;
- case 6:
- /* fourth param is minute. Convert it to a BCD number */
- ExtractBCD((char *)*(paramPtr->params[3]), &minute);
-
- /* fifth param is second. Convert it to a BCD number */
- ExtractBCD((char *)*(paramPtr->params[4]), &second);
-
- /* sixth param is block. Convert it to a BCD number */
- ExtractBCD((char *)*(paramPtr->params[5]), &block);
-
- result = AStop(paramPtr, ioRefNum, minute, second, block);
- if (result == noErr)
- {
- /* First param is minute. Convert it to a BCD number */
- ExtractBCD((char *)*(paramPtr->params[0]), &minute);
-
- /* Second param is second. Convert it to a BCD number */
- ExtractBCD((char *)*(paramPtr->params[1]), &second);
-
- /* Third param is block. Convert it to a BCD number */
- ExtractBCD((char *)*(paramPtr->params[2]), &block);
-
- result = APlay(paramPtr, ioRefNum, minute, second, block);
- }
- break;
- default:
- /* Report error in parameters by returning -1 */
- result = -1;
- break;
- }
-
- /* Convert result to string & return it */
- NumToStr(paramPtr, (long) result, &returnString);
- paramPtr->returnValue = PasToZero(paramPtr, (StringPtr) &returnString);
- }
-
- /************************************************************************
- *
- * Function: ExtractBCD
- *
- * Purpose: Extract number in BCD from PString
- *
- * Returns: nothing
- *
- * Side Effects: *track gets a new value
- *
- * Description: Extract number in BCD from Cstring "name".
- * "name" is always of the form "XX", where XX
- * ranges from "1" to "99"
- *
- ************************************************************************/
- void
- ExtractBCD(name, number)
- char *name;
- short *number;
- {
- short t;
-
- t = 0;
- while (*name != 0)
- {
- t *= 16;
- t += *name - '0';
- name++;
- }
-
- *number = t;
- }
-
- /************************************************************************
- *
- * Function: APlay
- *
- * Purpose: start playing at an absolute minute, second, block
- *
- * Returns: OSErr. Probably either
- * noErr everything's hunky-dory!
- * paramErr you messed up the call somehow.
- *
- * Side Effects: starts play. By default, this will play until the
- * end of the disc.
- *
- * Description: pass in the absolute minute, second and block in BCD.
- *
- ************************************************************************/
- OSErr
- APlay(paramPtr, refNum, minute, second, block)
- XCmdBlockPtr paramPtr;
- short refNum;
- short minute;
- short second;
- short block;
- {
- CDPlayParam myPB;
- short playMode;
- Handle refHandle;
-
- /* Get the global ioRefNum and convert it. */
- refHandle = GetGlobal(paramPtr, PLAYMODE);
- playMode = atoi(*(refHandle));
- DisposHandle(refHandle);
-
- myPB.ioCompletion = 0;
- myPB.ioNamePtr = (char *) 0;
- myPB.ioVRefNum = 1;
- myPB.ioCRefNum = refNum;
- myPB.csCode = APLAY;
-
- myPB.addrFormat = AMSFADDR;
- myPB.unused = 0; /* must be in BCD */
- myPB.minute = (char) minute; /* must be in BCD */
- myPB.second = (char) second; /* must be in BCD */
- myPB.block = (char) block; /* must be in BCD */
- myPB.stopAddress = 0;
- myPB.playMode = playMode;
- return (PBControl(&myPB, false));
- }
-
-
- /************************************************************************
- *
- * Function: BCDPosition
- *
- * Purpose: return BCD minute, second, block position
- *
- * Returns: OSErr. Probably either
- * noErr everything's hunky-dory!
- * paramErr you messed up the call somehow.
- *
- * Side Effects: none
- *
- * Description: Simply call the driver with a READQ call.
- * The absolute minute, second, block come back in
- * BCD. Return them.
- *
- ************************************************************************/
- OSErr
- BCDPosition(refNum, minute, second, block)
- short refNum;
- short *minute;
- short *second;
- short *block;
- {
- CDParam myPB;
- OSErr result;
-
- myPB.ioCompletion = 0;
- myPB.ioNamePtr = (char *) 0;
- myPB.ioVRefNum = 1;
- myPB.ioCRefNum = refNum;
- myPB.csCode = READQ;
-
- result = PBControl(&myPB, false);
-
- if (result == noErr)
- {
- *minute = (short) myPB.csParam[6];
- *second = (short) myPB.csParam[7];
- *block = (short) myPB.csParam[8];
- }
- return result;
- }
-
-
- /************************************************************************
- *
- * Function: AStop
- *
- * Purpose: stop playing at an absolute minute, second, block
- *
- * Returns: OSErr. Probably either
- * noErr everything's hunky-dory!
- * paramErr you messed up the call somehow.
- *
- * Side Effects: stops play.
- *
- * Description: pass in the absolute minute, second and block in BCD.
- *
- ************************************************************************/
- OSErr
- AStop(paramPtr, refNum, minute, second, block)
- XCmdBlockPtr paramPtr;
- short refNum;
- short minute;
- short second;
- short block;
- {
- CDPlayParam myPB;
- short playMode;
- Handle refHandle;
-
- /* Get the global ioRefNum and convert it. */
- refHandle = GetGlobal(paramPtr, PLAYMODE);
- playMode = atoi(*(refHandle));
- DisposHandle(refHandle);
-
- myPB.ioCompletion = 0;
- myPB.ioNamePtr = (char *) 0;
- myPB.ioVRefNum = 1;
- myPB.ioCRefNum = refNum;
- myPB.csCode = ASTOP;
-
- myPB.addrFormat = AMSFADDR;
- myPB.unused = 0;
- myPB.minute = (char) minute; /* must be in BCD */
- myPB.second = (char) second; /* must be in BCD */
- myPB.block = (char) block; /* must be in BCD */
- myPB.stopAddress = 0;
- myPB.playMode = playMode;
- return (PBControl(&myPB, false));
- }
-
-
- /************************************************************************
- *
- * Function: FindTrack1BCD
- *
- * Purpose: return start of track 1 in BCD
- *
- * Returns: OSErr. Probably either
- * noErr everything's hunky-dory!
- * paramErr you messed up the call somehow.
- *
- * Side Effects: modifies "minute", "second", and "block" to indicate
- * start of track 1.
- *
- * Description: Simply call the driver and return the values
- * byte that the driver gives us. See the developer's
- * guide for information about the READTOC command.
- *
- ************************************************************************/
- OSErr
- FindTrack1BCD(refNum, minute, second, block)
- short refNum;
- short *minute;
- short *second;
- short *block;
- {
- CDPlay3Param myPB;
- OSErr result;
- char track[4];
-
- myPB.ioCompletion = 0;
- myPB.ioNamePtr = (char *) 0;
- myPB.ioVRefNum = 1;
- myPB.ioCRefNum = refNum;
- myPB.csCode = READTOC;
- myPB.readType = 3;
- myPB.bufAddr = track;
- myPB.bufferLength = 4;
- myPB.track = 1;
-
- result = PBControl(&myPB, false);
- *minute = (short) track[1];
- *second = (short) track[2];
- *block = (short) track[3];
- return result;
- }
-
- /* C routines for HyperCard callbacks */
- #include <XCmdGlue.inc.c>
-